﻿//使用事件机制，模拟实现一个闹钟功能。闹钟可以有嘀嗒
//（Tick）事件和响铃（Alarm）两个事件。在闹钟走时时或
//者响铃时，在控制台/Winform界面上显示提示信息
using System;
namespace AlarmClock
{
    //定义一个委托类型，用于发布者发布Tick事件和响铃事件
    public delegate void AlarmEventHandler(object sender, EventArgs e);

    //发布者类
    public class Program
    {
        //私有成员
        private int hour;
        private int minute;
        private int second;
        //声明两个事件
        public event AlarmEventHandler? Tick;
        public event AlarmEventHandler? Alarm;
        //构造函数
        public Program(int h, int m, int s) => this.SetTime(h, m, s);
        //设置时间
        public void SetTime(int h, int m, int s)
        {
            hour = h;
            minute = m;
            second = s;
        }
        //发布Tick事件
        protected virtual void OnTick(EventArgs e)
        {
            Tick?.Invoke(this, e);
        }
        //发布Alarm事件
        protected virtual void OnAlarm(EventArgs e)
        {
            Alarm?.Invoke(this,e);
        }
        //启动闹钟
        public void Start()
        {
            while (true)
            {
                //显示闹钟时间
                Console.WriteLine("闹钟时间：{0:D2}:{1:D2}:{2:D2}", hour, minute, second);
                //每秒钟发布一次Tick事件
                OnTick(new EventArgs());
                //判断是否到达设定的时间
                if (second == 0)
                {
                    if (minute == 0)
                    {
                        if (hour == 0)
                        {
                            //时间为0时，闹钟响铃
                            OnAlarm(new EventArgs());
                            break;
                        }
                        else
                        {
                            hour--;
                            minute = 59;
                            second = 59;
                        }
                    }
                    else
                    {
                        minute--;
                        second = 59;
                    }
                }
                else
                {
                    second--;
                }
                //等待1秒钟
                System.Threading.Thread.Sleep(1000);
            }
        }
    }
    //订阅者类
    public class AlarmClockSubscriber
    {
        //订阅闹钟的Tick事件
        public void SubscribeTick(Program program)
        {
            program.Tick += Program_Tick;
        }
        //订阅闹钟的Alarm事件
        public void SubscribeAlarm(Program program)
        {
            program.Alarm += Program_Alarm;
        }
        //处理闹钟的Tick事件
        private void Program_Tick(object sender, EventArgs e)
        {
            Console.WriteLine("闹钟响起！");
        }
        //处理闹钟的Alarm事件
        private void Program_Alarm(object sender, EventArgs e)
        {
            Console.WriteLine("闹钟响铃！");
        }
    }
    class Executer
    {
        static void Main(string[] args)
        {
            //创建发布者
            var program = new Program(0, 1, 5);
            //订阅者订阅发布者的Tick和Alarm事件
            var subscriber = new AlarmClockSubscriber();
            //订阅事件
            subscriber.SubscribeTick(program);
            subscriber.SubscribeAlarm(program);
            //启动闹钟
            program.Start();
        }
    }
}
